package com.tfjybj.itoo.exam.provider.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dmsdbj.itoo.tool.base.service.impl.BaseServicePlusImpl;
import com.dmsdbj.itoo.tool.business.ItooResult;
import com.tfjybj.itoo.exam.entity.EvaluationRecordEntity;
import com.tfjybj.itoo.exam.entity.EvaluationSubEntity;
import com.tfjybj.itoo.exam.model.EvaluationPaperDetailModel;
import com.tfjybj.itoo.exam.model.EvaluationRecordModel;
import com.tfjybj.itoo.exam.model.EvaluationSubModel;
import com.tfjybj.itoo.exam.model.QuestionNaireAllInfoModel;
import com.tfjybj.itoo.exam.provider.dao.EvaluationRecordDao;
import com.tfjybj.itoo.exam.provider.dao.EvaluationSubDao;
import com.tfjybj.itoo.exam.provider.service.EvaluationPaperService;
import com.tfjybj.itoo.exam.provider.service.EvaluationRecordService;
import com.tfjybj.itoo.exam.provider.service.EvaluationSubService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.tfjybj.itoo.exam.provider.until.questionNaireConstants.doneChoose;
import static com.tfjybj.itoo.exam.provider.until.questionNaireConstants.multiSelect;

/**
 * TeEvaluationRecordService接口实现类
 * ${base}表
 *
 * @author 杨江涛
 * @version 2.0.0
 * @since 2.0.0 2018-12-18 18:19:48
 */
@Service("evaluationRecordService")
@Slf4j

public class EvaluationRecordServiceImpl extends BaseServicePlusImpl<EvaluationRecordDao, EvaluationRecordEntity> implements EvaluationRecordService {
    private static final String QUESTIONNAIRE_REDIS_INFO = "QUESTIONNAIRE_REDIS_INFO";

    //region 模板生成

    @Resource
    private EvaluationRecordDao teEvaluationRecordDao;
    @Resource
    private EvaluationRecordService teEvaluationRecordService;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private EvaluationPaperService evaluationPaperService;
    @Resource
    private EvaluationSubDao evaluationSubDao;
    @Resource
    private EvaluationSubService evaluationSubService;

    //endregion

    /* **********************************以下为非模板生成的内容********************************* */

    /**
     * 添加或更新问卷答题记录
     *
     * @param teEvaluationRecordEntity 问卷实体
     * @return 添加成功
     * @author 杨晓慧
     * @since 2.0.0 2018-12-25 18:19:48
     */
    @Override
    public ItooResult insertOrUpdateEvaluationRecord(EvaluationRecordEntity teEvaluationRecordEntity) {

        if (StringUtils.isEmpty(teEvaluationRecordEntity.getEvaluationMainId())) {
            log.warn("问卷题干id为空，填写的问卷答题记录-{}", teEvaluationRecordEntity);
            return ItooResult.build(ItooResult.FAIL, "问卷题干id为空");
        }
        if (StringUtils.isEmpty(teEvaluationRecordEntity.getQuestionCode())) {
            log.warn("问卷题型code为空，填写的问卷答题记录-{}", teEvaluationRecordEntity);
            return ItooResult.build(ItooResult.FAIL, "问卷题型code为空");
        }
        if (StringUtils.isEmpty(teEvaluationRecordEntity.getEvaluationSubId())) {
            log.warn("问卷答题选项为空，填写的问卷答题记录-{}", teEvaluationRecordEntity);
            return ItooResult.build(ItooResult.FAIL, "问卷答题选项id为空");
        }
        if (StringUtils.isEmpty(teEvaluationRecordEntity.getStudentId())) {
            log.warn("问卷学生id为空，填写的问卷答题记录-{}", teEvaluationRecordEntity);
            return ItooResult.build(ItooResult.FAIL, "问卷学生id为空");
        }
        if (StringUtils.isEmpty(teEvaluationRecordEntity.getPaperId())) {
            log.warn("问卷id为空，填写的问卷答题记录-{}", teEvaluationRecordEntity);
            return ItooResult.build(ItooResult.FAIL, "问卷id为空");
        }
        if (StringUtils.isEmpty(teEvaluationRecordEntity.getCourseId())) {
            log.warn("课程id为空，填写的问卷答题记录-{}", teEvaluationRecordEntity);
            return ItooResult.build(ItooResult.FAIL, "课程id为空");
        }

        String questionCode = teEvaluationRecordEntity.getQuestionCode();
        List<EvaluationRecordEntity> existRecord = isExistRecord(teEvaluationRecordEntity);

        boolean exist = existRecord.size() > 0;

        switch (questionCode) {
            case "1":
                if (exist) {
                    teEvaluationRecordEntity.setId(existRecord.get(0).getId());
                    //2.1 返回true时表示该答题记录已存在,需要更新记录
                    final boolean update = teEvaluationRecordService.updateById(teEvaluationRecordEntity);
                    if (update) {
                        log.info("课程问卷--更新单选题答题记录成功!");
                        return ItooResult.build(ItooResult.SUCCESS, "更新单选题答题记录成功！");
                    } else {
                        log.warn("课程问卷--更新单选题答题记录失败!答题记录--{}", teEvaluationRecordEntity);
                        return ItooResult.build(ItooResult.FAIL, "更新单选题答题记录失败！");
                    }
                } else {
                    //2.2 返回false时表示该答题记录不存在，需要添加问卷答题记录
                    final boolean save = teEvaluationRecordService.save(teEvaluationRecordEntity);
                    if (save) {
                        log.info("课程问卷--添加单选题答题记录成功!");
                        return ItooResult.build(ItooResult.SUCCESS, "添加单选题答题记录成功！");
                    } else {
                        log.warn("课程问卷--添加单选题答题记录失败!答题记录--{}", teEvaluationRecordEntity);
                        return ItooResult.build(ItooResult.FAIL, "添加单选题答题记录失败！");
                    }
                }

            case "2":
                // 多选题
                if (exist) {
                    //2.1返回true时表示该答题记录已存在,需要删除该记录
                    final boolean remove = teEvaluationRecordService.removeById(existRecord.get(0).getId());
                    if (remove) {
                        log.info("课程问卷--多选题重选删除上次答题记录成功!");
                        return ItooResult.build(ItooResult.SUCCESS, "多选题重选删除上次答题记录成功！");
                    } else {
                        log.warn("课程问卷--多选题重选删除上次答题记录失败!答题记录--{}", teEvaluationRecordEntity);
                        return ItooResult.build(ItooResult.FAIL, "多选题重选删除上次答题记录失败！");
                    }
                } else {
                    //2.2返回false时表示该答题记录不存在，需要添加问卷答题记录
                    final boolean save = teEvaluationRecordService.save(teEvaluationRecordEntity);
                    if (save) {
                        log.info("课程问卷--多选题添加答题记录成功!");
                        return ItooResult.build(ItooResult.SUCCESS, "多选题添加答题记录成功！");
                    } else {
                        log.warn("课程问卷--多选题添加答题记录失败!答题记录--{}", teEvaluationRecordEntity);
                        return ItooResult.build(ItooResult.FAIL, "多选题添加答题记录失败！");
                    }
                }
            default:
                log.warn("课程问卷--添加答题记录失败!答题记录--{}", teEvaluationRecordEntity);
                return ItooResult.build(ItooResult.FAIL, "添加答题记录失败！");
        }
    }


    /**
     * 返回题目的答题记录是否存在
     *
     * @param teEvaluationRecordEntity 问卷实体
     * @return list 存在的记录
     * @author 杨晓慧
     * @since 2.0.0 2018-12-25 18:19:48
     */
    public List<EvaluationRecordEntity> isExistRecord(EvaluationRecordEntity teEvaluationRecordEntity) {

        String questionCode = teEvaluationRecordEntity.getQuestionCode();
        String evaluationMainId = teEvaluationRecordEntity.getEvaluationMainId();
        String evaluationSubId = teEvaluationRecordEntity.getEvaluationSubId();
        String studentId = teEvaluationRecordEntity.getStudentId();
        String courseId = teEvaluationRecordEntity.getCourseId();
        String paperId = teEvaluationRecordEntity.getPaperId();

        QueryWrapper<EvaluationRecordEntity> queryWrapper = new QueryWrapper<>();

        switch (questionCode) {
            case "1":
                // 单选题时，判断问卷id,题干id，学生id是否存在
                queryWrapper.eq("evaluation_main_id", evaluationMainId);
                queryWrapper.eq("course_id", courseId);
                queryWrapper.eq("student_id", studentId);
                queryWrapper.eq("paper_id", paperId);
                break;

            case "2":
                // 多选题时，判断问卷id,题干id，选项id，学生id是否存在
                queryWrapper.eq("evaluation_main_id", evaluationMainId);
                queryWrapper.eq("evaluation_sub_id", evaluationSubId);
                queryWrapper.eq("course_id", courseId);
                queryWrapper.eq("student_id", studentId);
                queryWrapper.eq("paper_id", paperId);
                break;
            default:
                log.warn("判断问卷答题记录是否存在题型参数传入错误，实体信息-{}", teEvaluationRecordEntity);
        }
        return teEvaluationRecordService.list(queryWrapper);
    }

    /**
     * 查询该题干的作答总人数
     *
     * @param paperId          问卷id
     * @param schoolYearId     学期学年id
     * @param courseId         课程id
     * @param evaluationMainId 题干id
     * @return paperId, schoolYearId, courseId, evaluationMainId
     * @author 杨晓慧
     * @since 2.0.0 2018-12-28 17:19:44
     */
    @Override
    public Integer queryParticipationNumber(String paperId, String schoolYearId, String courseId, String evaluationMainId) {
        return teEvaluationRecordDao.queryParticipationNumber(paperId, schoolYearId, courseId, evaluationMainId);
    }

    /**
     * 查某一个问题下的学生作答各选项的比例
     *
     * @param paperId          问卷id
     * @param schoolYearId     学期学年id
     * @param courseId         课程id
     * @param evaluationMainId 题干id
     * @return 各选项的比例
     * @author 杨江涛
     * @since 2.0.0 2019年3月20日19:21:30
     */
    @Override
    public List<EvaluationRecordModel> queryOptionRatioResult(String paperId, String schoolYearId, String courseId, String evaluationMainId) {
        List<EvaluationRecordModel> teEvaluationRecordModels = teEvaluationRecordDao.queryOptionRatioResult(paperId, schoolYearId, courseId, evaluationMainId);
        // 遍历结果集，如果题型是单选题，则根据选项id查询选项内容
        if (teEvaluationRecordModels.get(0).getQuestionCode().equals("1")) {
            //根据选项id查询选项内容
            int i = 0;
            for (EvaluationRecordModel tel : teEvaluationRecordModels) {
                EvaluationSubEntity evaluationSubEntity = evaluationSubService.getById(tel.getEvaluationSubId());
                teEvaluationRecordModels.get(i).setOptionContent(evaluationSubEntity.getOptionContent());
                teEvaluationRecordModels.get(i).setQuestionScore(Double.parseDouble(evaluationSubEntity.getOptionScore() + ""));
                // 查询record表中包含某选项id的总人数
                String studentCheckedNum = teEvaluationRecordService.queryOptionSelectedNumberBySubId(paperId, schoolYearId, courseId, evaluationMainId, tel.getEvaluationSubId());
                // 将选择该选项的总人数放入model中
                teEvaluationRecordModels.get(i).setStudentCheckedNum(studentCheckedNum);
                i++;
            }
            i = 0;
            return teEvaluationRecordModels;
        } else if (teEvaluationRecordModels.get(0).getQuestionCode().equals("2")) {
            // 如果题型是多选题，则将|分割的字符串分为多条数据返回
            String[] split = teEvaluationRecordModels.get(0).getEvaluationSubId().split("\\|");
            List<EvaluationRecordModel> teEvaluationRecordList = new ArrayList<>();
            for (int i = 0; i < split.length; i++) {
                EvaluationRecordModel teEvaluationRecordModel = new EvaluationRecordModel();
                org.springframework.beans.BeanUtils.copyProperties(teEvaluationRecordModels.get(0), teEvaluationRecordModel);
                teEvaluationRecordModel.setEvaluationSubId(split[i]);
                teEvaluationRecordList.add(teEvaluationRecordModel);
            }
            //根据选项id查询选项内容
            int i = 0;
            for (EvaluationRecordModel tel : teEvaluationRecordList) {
                EvaluationSubEntity evaluationSubEntity = evaluationSubService.getById(tel.getEvaluationSubId());
                teEvaluationRecordList.get(i).setOptionContent(evaluationSubEntity.getOptionContent());
                teEvaluationRecordList.get(i).setQuestionScore(Double.parseDouble(evaluationSubEntity.getOptionScore() + ""));
                // 查询record表中包含某选项id的总人数
                String studentCheckedNum = teEvaluationRecordService.queryOptionSelectedNumberBySubId(paperId, schoolYearId, courseId, evaluationMainId, tel.getEvaluationSubId());
                // 将选择该选项的总人数放入model中
                teEvaluationRecordList.get(i).setStudentCheckedNum(studentCheckedNum);
                i++;
            }
            teEvaluationRecordModels = teEvaluationRecordList;
            i = 0;
            return teEvaluationRecordModels;
        }
        return teEvaluationRecordModels;
    }
    /**
         * 实时更新问卷记录
         * @param
         * @return Boolean
         * @author 魏恩君
         * @since 2.0.0 2019/3/20
     */
    @Override
    public Boolean updateEvaluationRecord(EvaluationRecordModel model){
        // 1.从redis里取出该学生的问卷记录
        Boolean flag = true;
        String keyName = QUESTIONNAIRE_REDIS_INFO + ":" + model.getCourseId() + ":" + model.getPaperId() + ":" + model.getStudentId();
        QuestionNaireAllInfoModel questionNaireAllInfoModel = (QuestionNaireAllInfoModel) redisTemplate.opsForValue().get(keyName);

        // 2.判断redis里是否有记录
        // 2.1如果redis里有问卷记录,则直接从redis里取出记录进行处理
        if(questionNaireAllInfoModel != null || questionNaireAllInfoModel.getTeEvaluationPaperDetailModels().size() > 0){
            // 取出具体到题的记录
            List<EvaluationPaperDetailModel> detailList = questionNaireAllInfoModel.getTeEvaluationPaperDetailModels();

            // 判断题型,这里是问卷的单选题和多选题处理
            // 如果是多选题
            if(multiSelect.equals(model.getQuestionCode())){
                // 循环遍历试卷中的每一道题
                for(EvaluationPaperDetailModel detailModel : detailList){
                    // 如果试题id等于此题的id
                    if(detailModel.getEvaluationMainId() == model.getEvaluationMainId() || detailModel.getEvaluationMainId().equals(model.getEvaluationMainId())){
                        // 取出此道题的所有选项
                        List<EvaluationSubModel> subList = detailModel.getEvaluationSubModelList();
                        // 定义一个已选选项的list
                        List<String> doneSubList = new ArrayList<>();
                        // 循环遍历所有的选项
                        for (EvaluationSubModel sub:subList){
                            // 先取出所有已选答案,放到一个list,此处为更新数据库操作使用
                            if(doneChoose.equals(sub.getAnswer())){
                                doneSubList.add(sub.getOptionId());
                            }

                            // 此处为redis更新操作
                            // 如果选项等于此次操作选中的选项
                            if(sub.getOptionId().equals(model.getEvaluationSubId())){
                                //如果这个选项已经选了,说明此次操作是取消选择操作
                                if(doneChoose.equals(sub.getAnswer())){
                                    sub.setAnswer("false");
                                } else {
                                    // 如果没有选,说明此次操作时选中操作
                                    sub.setAnswer("true");
                                    detailModel.setDone(true);
                                }
                            }
                            // 如果选项不等于此次操作选中的选项
                            else{
                                //如果选项已选,则保持已选状态
                                if(doneChoose.equals(sub.getAnswer())){
                                    sub.setAnswer("true");
                                    detailModel.setDone(true);
                                } else {
                                    // 如果选项没选,则保持未选状态
                                    sub.setAnswer("false");
                                }
                            }
                        }
                        // 将学生答案更新到数据库
                        // 将此次操作本道题的选项加入到已选项中
                        List<String> doneList = new ArrayList<>();
                        doneList.addAll(doneSubList);

                        if(doneSubList.size() >0){
                            for(String doneSub:doneSubList){
                                // 如果已选项中有此次选中的选项,表示取消此选项
                                if(doneSub.equals(model.getEvaluationSubId())){
                                    doneList.remove(doneSub);
                                    break;
                                }
                                // 如果已选项中没有此次选中的选项,表示选中了此选项
                                else{
                                    if(!doneSubList.contains(model.getEvaluationSubId())){
                                        doneList.add(model.getEvaluationSubId());
                                        break;
                                    }
                                    continue;
                                }
                            }
                            // 将list用分隔符隔开,成为一个字符串,赋给学生已选选项字段
                            //model.setEvaluationSubId(Joiner.on("|").join(doneSubList));
                            model.setEvaluationSubId(org.apache.commons.lang3.StringUtils.join(doneList.toArray(new String[doneList.size()]), "|"));
                        }


                        // 更新此道题答案到数据库
                        if(model.getRecordId() != null && !"".equals(model.getRecordId())){
                            flag = teEvaluationRecordDao.updateEvaluationRecordById(model);

                        }else{
                            flag = teEvaluationRecordDao.updateEvaluationRecord(model);
                        }

                        if(flag == false){
                            log.error("有redis情况下更新问卷多选题记录表失败,学生id为{},问卷id为{},课程id为{},学年学期id为{}",model.getStudentId(),model.getPaperId(),model.getCourseId(),model.getSchoolYearId());
                            return false;
                        }
                    }
                }
            } else {
                // 如果是单选
                // 将redis里的对应题的对应选项设置为已选
                for(EvaluationPaperDetailModel detailModel : detailList){
                    if(detailModel.getEvaluationMainId().equals(model.getEvaluationMainId()) || detailModel.getEvaluationMainId() == model.getEvaluationMainId()){
                        List<EvaluationSubModel> subList = detailModel.getEvaluationSubModelList();
                        for (EvaluationSubModel sub:subList){
                            if(sub.getOptionId().equals(model.getEvaluationSubId())){
                                sub.setAnswer("true");
                            }
                            else{
                                sub.setAnswer("false");
                            }
                        }
                        detailModel.setDone(true);
                    }
                }

                // 更新此道题答案到数据库
                // 更新此道题答案到数据库
                if(model.getRecordId() != null && !"".equals(model.getRecordId())){
                    flag = teEvaluationRecordDao.updateEvaluationRecordById(model);
                }else{
                    flag = teEvaluationRecordDao.updateEvaluationRecord(model);
                }

                if(flag == false){
                    log.error("有redis情况下更新问卷单选题记录表失败,学生id为{},问卷id为{},课程id为{},学年学期id为{}",model.getStudentId(),model.getPaperId(),model.getCourseId(),model.getSchoolYearId());
                    return false;
                }
            }
            redisTemplate.opsForValue().set(keyName,questionNaireAllInfoModel,3600*4, TimeUnit.SECONDS);
        }
        // 2.2 如果redis没有问卷记录,则从数据库库中取出记录进行处理
        else{
            // 2.2.1更新数据库操作
            // 先判断题型,如果是多选题
            if(multiSelect.equals(model.getQuestionCode())){
                // 查询数据库中此道题答案
                String checkedSub = "";
                if(model.getRecordId() != null && !"".equals(model.getRecordId())){
                    checkedSub = teEvaluationRecordDao.queryAnswerById(model.getRecordId());
                }else{
                    checkedSub = teEvaluationRecordDao.queryAnswer(model.getCourseId(),model.getPaperId(),model.getEvaluationMainId(),model.getStudentId(),model.getSchoolYearId());
                }

                if(!"".equals(checkedSub) && checkedSub != null){
                    // 分割字符串,赋给一个List
                    List<String> checkSubList = new ArrayList<>(Arrays.asList(checkedSub.split("\\|")));

                    Boolean isContains = true;
                    // 对答案进行处理
                    for(String checkSubString : checkSubList){
                        if(checkSubString ==  model.getEvaluationSubId() || checkSubString.equals(model.getEvaluationSubId())){
                            checkSubList.remove(model.getEvaluationSubId());
                            isContains = true;
                            break;
                        }
                        else{
                            isContains = false;
                        }
                    }

                    if(!isContains){
                        checkSubList.add(model.getEvaluationSubId());
                    }

                    //加上分隔符
                    model.setEvaluationSubId(org.apache.commons.lang3.StringUtils.join(checkSubList.toArray(), "|"));
                }

                //model.setEvaluationSubId(Joiner.on("|").join(checkSubList));
                // 更新数据库
                // 更新此道题答案到数据库
                if(model.getRecordId() != null && !"".equals(model.getRecordId())){
                    flag = teEvaluationRecordDao.updateEvaluationRecordById(model);

                }else{
                    flag = teEvaluationRecordDao.updateEvaluationRecord(model);
                }
                if(flag == false){
                    log.error("没有redis情况下更新问卷多选题记录表失败,学生id为{},问卷id为{},课程id为{},学年学期id为{}",model.getStudentId(),model.getPaperId(),model.getCourseId(),model.getSchoolYearId());
                    return false;
                }
            }else{
                //如果是单选题,则直接更新数据库
                // 更新此道题答案到数据库
                if(model.getRecordId() != null && !"".equals(model.getRecordId())){
                    flag = teEvaluationRecordDao.updateEvaluationRecordById(model);
                }else{
                    flag = teEvaluationRecordDao.updateEvaluationRecord(model);
                }
            }

            // 2.2.2放入redis
            QuestionNaireAllInfoModel questionNaireModel = evaluationPaperService.queryNaireAndRecord(model.getPaperId(),model.getCourseId(),model.getStudentId(),model.getSchoolYearId());
            redisTemplate.opsForValue().set(keyName,questionNaireModel,3600*4,TimeUnit.SECONDS);

        }
        return flag;
    }
    /**
     * 查某一个问题下的学生作答当前选项的总人数
     *
     * @param paperId          问卷id
     * @param schoolYearId     学期学年id
     * @param courseId         课程id
     * @param evaluationMainId 题干id
     * @param evaluationSubId  选项id
     * @return 某一个问题下的学生作答当前选项的总人数
     * @author 杨江涛
     * @since 2.0.0 2019-3-22 16:26:56
     */
    @Override
    public String queryOptionSelectedNumberBySubId(String paperId, String schoolYearId, String courseId, String evaluationMainId, String evaluationSubId) {
        return teEvaluationRecordDao.queryOptionSelectedNumberBySubId(paperId, schoolYearId, courseId, evaluationMainId, evaluationSubId);
    }
}
